package org.wdz.linuxOperation;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import com.jcraft.jsch.SftpException;
import org.springframework.util.StringUtils;
import org.wdz.util.SFTPUtil;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * 远程执行linux的shell script
 * @author Ickes
 * @author2 hpp
 * @since  V0.2
 */
public class RemoteExecuteCommand {
    //字符编码默认是utf-8
    private static String  DEFAULTCHART="UTF-8";
    private static Connection conn;
    private String ip;
    private String userName;
    private String userPwd;

    public RemoteExecuteCommand(String ip, String userName, String userPwd) {
        this.ip = ip;
        this.userName = userName;
        this.userPwd = userPwd;
    }

    public RemoteExecuteCommand() {

    }

    /**
     * 远程登录linux的主机
     * @author Ickes
     * @since  V0.1
     * @return
     *      登录成功返回true，否则返回false
     */
    public Boolean login(){
        boolean flg=false;
        try {
            conn = new Connection(ip);
            conn.connect();//连接
            flg=conn.authenticateWithPassword(userName, userPwd);//认证
            if (flg){
                System.out.println("认证成功！");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return flg;
    }
    /**
     * @author Ickes
     * 远程执行shll脚本或者命令
     * @param cmd
     *      即将执行的命令
     * @return
     *      命令执行完后返回的结果值
     * @since V0.1
     */
    public String execute(String cmd){
        String result="";
        try {
            if(login()){
                Session session= conn.openSession();//打开一个会话
                session.execCommand(cmd);//执行命令
                result=processStdout(session.getStdout(),DEFAULTCHART);
                //如果为得到标准输出为空，说明脚本执行出错了
                if(StringUtils.isEmpty(result)){
                    result=processStdout(session.getStderr(),DEFAULTCHART);
                }
                conn.close();
                session.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * @author Ickes
     * 远程执行shll脚本或者命令
     * @param cmd
     *      即将执行的命令
     * @return
     *      命令执行成功后返回的结果值，如果命令执行失败，返回空字符串，不是null
     * @since V0.1
     */
    public String executeSuccess(String cmd){
        String result="";
        try {
            if(login()){
                Session session= conn.openSession();//打开一个会话
                session.execCommand(cmd);//执行命令
                result=processStdout(session.getStdout(),DEFAULTCHART);
                conn.close();
                session.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 解析脚本执行返回的结果集
     * @author Ickes
     * @param in 输入流对象
     * @param charset 编码
     * @since V0.1
     * @return
     *       以纯文本的格式返回
     */
    public static String processStdout(InputStream in, String charset){
        InputStream    stdout = new StreamGobbler(in);
        StringBuffer buffer = new StringBuffer();;
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(stdout,charset));
            String line=null;
            while((line=br.readLine()) != null){
                buffer.append(line+"\n");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer.toString();
    }

    //执行启动的命令
    public void startUp(String jarName){
        //编写shell启动文件并上传到远程服务器
        String host = "119.29.56.176";
        String pwd = "!wuchuan1258";
        int port = 22;
        String user = "root";
        String filename = jarName+"_run.sh";
        SFTPUtil sftpUtil = new SFTPUtil(user,pwd,host,port);
        sftpUtil.login();
        //while(!sftpUtil.isEntity("/usr/local/java/"+filename)){
            String basePath = "/usr/local";
            String t = "#!/bin/bash\n" +
                    "# 定义变量\n" +
                    "# 要运行的jar包路径，加不加引号都行。 注意：等号两边 不能 有空格，否则会提示command找不到\n" +
                    "JAR_NAME=\"article.jar\"\n" +
                    "# 日志路径，加不加引号都行。 注意：等号两边 不能 有空格，否则会提示command找不到\n" +
                    "LOG_PATh=article.out\n" +
                    "\n" +
                    "\n" +
                    "# 如果输入格式不对，给出提示！\n" +
                    "tips() {\n" +
                    "        echo \"\"\n" +
                    "        echo \"WARNING!!!......Tips, please use command: sh auto_deploy.sh [start|stop|restart|status].   For example: sh auto_deploy.sh start  \"\n" +
                    "        echo \"\"\n" +
                    "        exit 1\n" +
                    "}\n" +
                    "\n" +
                    "\n" +
                    "# 启动方法\n" +
                    "start() {\n" +
                    "        # 重新获取一下pid，因为其它操作如stop会导致pid的状态更新\n" +
                    "        pid=`ps -ef | grep $JAR_NAME | grep -v grep | awk '{print $2}'`\n" +
                    "        # -z 表示如果$pid为空时执行\n" +
                    "        if [ -z $pid ]; then\n" +
                    "        nohup java -jar -Xms64M -Xmx128M -XX:PermSize=64M -XX:MaxPermSize=128m -Dspring.profiles.active=pro $JAR_NAME > $LOG_PATh &\n" +
                    "        pid=`ps -ef | grep $JAR_NAME | grep -v grep | awk '{print $2}'`\n" +
                    "                echo \"\"\n" +
                    "        echo \"Service ${JAR_NAME} is starting！pid=${pid}\"\n" +
                    "                echo \"........................Here is the log..............................\"\n" +
                    "                echo \".....................................................................\"\n" +
                    //"        tail -f $LOG_PATh\n" +
                    "                echo \"........................Start successfully！.........................\"\n" +
                    "        else\n" +
                    "                echo \"\"\n" +
                    "                echo \"Service ${JAR_NAME} is already running,it's pid = ${pid}. If necessary, please use command: sh auto_deploy.sh restart.\"\n" +
                    "                echo \"\"\n" +
                    "        fi\n" +
                    "}\n" +
                    "\n" +
                    "# 停止方法\n" +
                    "stop() {\n" +
                    "                # 重新获取一下pid，因为其它操作如start会导致pid的状态更新\n" +
                    "        pid=`ps -ef | grep $JAR_NAME | grep -v grep | awk '{print $2}'`\n" +
                    "        # -z 表示如果$pid为空时执行。 注意：每个命令和变量之间一定要前后加空格，否则会提示command找不到\n" +
                    "        if [ -z $pid ]; then\n" +
                    "                echo \"\"\n" +
                    "        echo \"Service ${JAR_NAME} is not running! It's not necessary to stop it!\"\n" +
                    "                echo \"\"\n" +
                    "        else\n" +
                    "                kill -9 $pid\n" +
                    "                echo \"\"\n" +
                    "                echo \"Service stop successfully！pid:${pid} which has been killed forcibly!\"\n" +
                    "                echo \"\"\n" +
                    "        fi\n" +
                    "}\n" +
                    "\n" +
                    "# 输出运行状态方法\n" +
                    "status() {\n" +
                    "        # 重新获取一下pid，因为其它操作如stop、restart、start等会导致pid的状态更新\n" +
                    "        pid=`ps -ef | grep ${JAR_NAME} | grep -v grep | awk '{print $2}'`\n" +
                    "        # -z 表示如果$pid为空时执行。注意：每个命令和变量之间一定要前后加空格，否则会提示command找不到\n" +
                    "        if [ -z $pid ];then\n" +
                    "                echo \"\"\n" +
                    "        echo \"Service ${JAR_NAME} is not running!\"\n" +
                    "                echo \"\"\n" +
                    "        else\n" +
                    "                echo \"\"\n" +
                    "        echo \"Service ${JAR_NAME} is running. It's pid=${pid}\"\n" +
                    "                echo \"\"\n" +
                    "        fi\n" +
                    "}\n" +
                    "\n" +
                    "# 重启方法\n" +
                    "restart() {\n" +
                    "        echo \"\"\n" +
                    "        echo \".............................Restarting..............................\"\n" +
                    "        echo \".....................................................................\"\n" +
                    "                # 重新获取一下pid，因为其它操作如start会导致pid的状态更新\n" +
                    "        pid=`ps -ef | grep $JAR_NAME | grep -v grep | awk '{print $2}'`\n" +
                    "        # -z 表示如果$pid为空时执行。 注意：每个命令和变量之间一定要前后加空格，否则会提示command找不到\n" +
                   // "        while [ ! -z $pid ]; do\n" +
                    "                kill -9 $pid\n" +
                   // "        pid=`ps -ef | grep $JAR_NAME | grep -v grep | awk '{print $2}'`\n" +
                    //"        done\n" +
                   // "        while [ -z $pid ]; do\n" +
                    "        nohup java -jar -Xms64M -Xmx128M -XX:PermSize=64M -XX:MaxPermSize=128m -Dspring.profiles.active=pro $JAR_NAME > $LOG_PATh &\n" +
                    "        pid=`ps -ef | grep $JAR_NAME | grep -v grep | awk '{print $2}'`\n" +
                    //"        done\n" +
                    "        echo \"pid = $pid\"\n" +
                    "        echo \"....................Restart successfully！...........................\"\n" +
                    "}\n" +
                    "\n" +
                    "# 根据输入参数执行对应方法，不输入则执行tips提示方法\n" +
                    "case \"$1\" in\n" +
                    "   \"start\")\n" +
                    "     start\n" +
                    "     ;;\n" +
                    "   \"stop\")\n" +
                    "     stop\n" +
                    "     ;;\n" +
                    "   \"status\")\n" +
                    "     status\n" +
                    "     ;;\n" +
                    "   \"restart\")\n" +
                    "     restart\n" +
                    "     ;;\n" +
                    "   *)\n" +
                    "     tips\n" +
                    "     ;;\n" +
                    "esac\n";
            InputStream inputStream = new ByteArrayInputStream(t.getBytes(StandardCharsets.UTF_8));
            try {
                sftpUtil.upload(basePath, "/java", filename, inputStream);
            } catch (SftpException e) {
                e.printStackTrace();
            }
       // }

        RemoteExecuteCommand rec=new RemoteExecuteCommand(host, user,pwd);

        //执行命令
        try {
            if(rec.login()){

                System.out.println("=====第一个步骤=====");
                Session session= conn.openSession();//打开一个会话

                //TODO:多条命令
                session.execCommand("cd ../usr/local/java&&sh article_run.sh restart",DEFAULTCHART);//执行命令
                String result =  processStdout(session.getStdout(),DEFAULTCHART);
                System.out.println(result);
                session.close();
                conn.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {


    }



    public static void setCharset(String charset) {
        DEFAULTCHART = charset;
    }
    public Connection getConn() {
        return conn;
    }
    public void setConn(Connection conn) {
        this.conn = conn;
    }
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserPwd() {
        return userPwd;
    }
    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }
}
